import os
import sys
sys.path.append(".")

from Engine.engine import BacktestingEngine, OptimizationSetting, BacktestingMode, CommissionRate
from strategies.spread_strategy_parabola import (
    SpreadStrategyParabola
)
from common.constant import (Direction, Offset, Exchange, 
                                  Interval, Status)
from datetime import datetime, date
import json
import signal
from collections import defaultdict, OrderedDict
import pandas as pd
import inspect
from strategies.combine_strategy import CombineStrategy


backtest = \
      {
                'vt_symbols': ["BTCUSDT.spot", "BTCUSDT.perp"],
                'exchanges': [Exchange.BINANCE, Exchange.BINANCE],
                "data_start_date": datetime(2024, 9, 15),
                "data_end_date": datetime(2024, 11, 26),
                "trading_start_date": date(2024, 9, 20),
                "rate": CommissionRate(0, 0.0002, 0, 0.0002, 0, 0),
                "size": 10,
                "price_tick": 0.01,
                "capital": 1_000_000,
            }
   
   


def term(sig_num, addtion):
    print('current pid is %s, group id is %s' % (os.getpid(), os.getpgrp()))
    os.killpg(os.getpgid(os.getpid()), signal.SIGKILL)


if __name__ == "__main__":
    signal.signal(signal.SIGTERM, term)

    setting_results = defaultdict(OrderedDict)

    print(datetime.now(), "start backtesting")
    engine = BacktestingEngine()
    engine.set_parameters(
        vt_symbols=backtest["vt_symbols"],
        exchanges=backtest["exchanges"],
        interval="1m",
        start=backtest["data_start_date"],
        end=backtest["data_end_date"],
        rate=backtest["rate"],
        slippage=0,
        size=backtest["size"],
        pricetick=backtest["price_tick"],
        capital=backtest["capital"],
        mode=BacktestingMode.BAR
    )
    settings = [{'ma_type': 'parabola', 'ma_length': 600, 'grid_levels': [1], 'spread_grid_std_multi': 0.8, 'min_grid_step': 2, 'slope_adjust_ratio': 0.15}
]

    engine.add_strategy(CombineStrategy, {})
    for setting in settings:
        engine.strategy.add_strategy(SpreadStrategyParabola, SpreadStrategyParabola.__name__, engine.vt_symbols, setting)

    engine.set_start_date(backtest["trading_start_date"])
    engine.load_data()
    engine.run_backtesting()
    df = engine.calculate_result()
    engine.calculate_statistics()
    engine.save_backtest_result("backtest_result")
    engine.show_chart(engine.daily_df)
    for sub_strategy in engine.strategy.strategy_list:
        diff_df = sub_strategy.diff_df
        sub_sid = sub_strategy.sub_strategy_id
        df = engine.sub_daily_df[sub_sid]

        diff_df["trades"] = ""

        diff_len = len(diff_df)
        dt_index = 0

        sub_trades = {k:v for k,v in engine.trades.items() if v.sub_strategy_id == sub_sid}

        for dt, trades in df.trades.items():
            size = len(trades)
            if size == 0:
                continue
            for i in range(0, size, 2):
                trade1 = trades[i]
                trade2 = trades[i+1]
                price = trade1.price - trade2.price
                while dt_index < (diff_len -1) and diff_df.index[dt_index] < trade1.datetime:
                    dt_index += 1
                diff_df.loc[diff_df.index[dt_index], "trades"] += str(price) + ":" + trade1.offset.name + ":" + trade1.direction.name + ";"
                

        diff_df.to_csv(f"parabola_diff_df_{str(sub_strategy.sub_strategy_id)}.csv")
        df.to_csv(f"parabola_daily_df_{str(sub_strategy.sub_strategy_id)}.csv")
        with open(f"parabola_trades_{str(sub_strategy.sub_strategy_id)}.json", "w") as f:
            json.dump(sub_trades, f, cls=engine.EngineEncoder, indent=2)

    print(datetime.now(), "end backtesting")


